package com.gddb.xwj.utils;

import com.gddb.xwj.common.entity.TestEntity;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.sql.Timestamp;

/**
 * @Author xuwj
 * @Description: 反射工具类
 * @CreateTime 2020/1/9 23:25
 * @Version 1.0
 */
@Slf4j
public class ReflectionUtil {

    /**
     * 封装当前类和父类的所有属性，拼接属性sql
     *
     * @param obj
     * @return
     */
    public static String getAllField(Object obj) {
        if (null == obj) {
            return null;
        }
        //获取class文件
        Class<?> aClass = obj.getClass();
        //获取当前类的声明属性
        Field[] declaredFields = aClass.getDeclaredFields();
        //转换为sql字符串
        String s1 = getField2SqlStr(declaredFields);
        Field[] parentDeclaredFields = aClass.getSuperclass().getDeclaredFields();
        String s2 = getField2SqlStr(parentDeclaredFields);
        return s1 + "," + s2;
    }

    /**
     * 属性转换sqlStr
     *
     * @param declaredFields
     * @return
     */
    public static String getField2SqlStr(Field[] declaredFields) {
        StringBuffer sf = new StringBuffer();
        for (int i = 0; i < declaredFields.length; i++) {
            sf.append(declaredFields[i].getName());
            if (i < declaredFields.length - 1) {
                sf.append(",");
            }
        }
        return sf.toString();
    }

    /**
     * 获取当前类和父类的所有属性值
     *
     * @param obj
     * @return
     */
    public static String getAllFieldValue(Object obj) {
        if (null == obj) {
            return null;
        }
        //获取类文件
        Class<?> aClass = obj.getClass();
        //获取类的声明属性
        Field[] declaredFields = aClass.getDeclaredFields();
        //根据当前对象，获取属性值并转换为sql字符串
        String s1 = getFieldValue2SqlStr(obj, declaredFields);
        Field[] parentDeclaredFields = aClass.getSuperclass().getDeclaredFields();
        String s2 = getFieldValue2SqlStr(obj, parentDeclaredFields);
        return s1 + "," + s2;
    }

    /**
     * //根据当前对象，获取属性值并转换为sql字符串
     *
     * @param obj
     * @param declaredFields
     * @return
     */
    public static String getFieldValue2SqlStr(Object obj, Field[] declaredFields) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < declaredFields.length; i++) {
            try {
                //获取声明属性
                Field declaredField = declaredFields[i];
                //允许操作私有属性
                declaredField.setAccessible(true);
                //获取属性值
                Object value = declaredField.get(obj);
                ///如果属性值是字符串类型，需要做特殊处理
                if (null != value && value instanceof String) {
                    sb.append("'");
                    sb.append(value);
                    sb.append("'");
                }
                //
                //其他类型
                //
                //时间戳类型处理
                else if (null != value && value instanceof Timestamp){
                    sb.append("'");
                    sb.append(value);
                    sb.append("'");
                }
                else {
                    sb.append(value);
                }
                if (i < declaredFields.length - 1) {
                    sb.append(",");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    /**
     * 设置属性值，用于更新字段操作
     *
     * @param obj
     * @return
     */
    public static String setAllFieldValue(Object obj) {
        if (null == obj) {
            return null;
        }
        //获取类文件
        Class<?> aClass = obj.getClass();
        //获取声明属性
        Field[] declaredFields = aClass.getDeclaredFields();
        //获取属性值并转换为sql
        String s1 = setFieldValue2SqlStr(declaredFields, obj);
        Field[] parentDeclaredFields = aClass.getSuperclass().getDeclaredFields();
        String s2 = setFieldValue2SqlStr(parentDeclaredFields, obj);
        return s1 + "," + s2;
    }

    public static String setFieldValue2SqlStr(Field[] declaredFields, Object obj) {
        StringBuffer sb = new StringBuffer();
        try {
            int count = 0;
            for (int i = 0; i < declaredFields.length; i++) {
                Field declaredField = declaredFields[i];
                declaredField.setAccessible(true);
                Object value = declaredField.get(obj);
                if (null == value) {
                    continue;
                }
                count++;
                sb.append(declaredField.getName() + " = '" + value + "'");
                if (count > 1 && i < declaredFields.length - 1) {
                    sb.append(",");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    /**
     * 测试用
     *
     * @param args
     */
    public static void main(String[] args) {
        TestEntity testEntity = new TestEntity();
        testEntity.setUserName("许文杰");
        testEntity.setPassword("123");
        testEntity.setEmail("test@163.com");
        testEntity.setPhone("13008889302");
        testEntity.setCreateTime(DateUtil.getTimestamp());
        testEntity.setUpdateTime(DateUtil.getTimestamp());

        String field = getAllField(testEntity);
        String value = getAllFieldValue(testEntity);

        log.info("\r\n 字段：{} ### \r\n 值:{}", field, value);
    }
}
